//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.IO;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Data.Configuration.Design;
using EntLibContrib.Resource.Configuration;
using EntLibContrib.Resource.Configuration.Design;

#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
#endif

namespace EntLibContrib.Resource.Configuration.Design.Tests
{
	[TestClass]
	public class ResourceDatabaseConfigurationDesignManagerFixture : ConfigurationDesignHost
	{
		protected override void InitializeCore()
		{
		}

		[TestMethod]
		public void RegisterTest()
		{
			ResourceDatabaseConfigurationDesignManager manager = new ResourceDatabaseConfigurationDesignManager();
			manager.Register(ServiceProvider);
		}

		[TestMethod]
		public void OpenAndSaveConfiguration()
		{
			using(new ConfigFileSnapshot())
			{
				ApplicationNode.Hierarchy.Load();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);
				ApplicationNode.Hierarchy.Open();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);

				ResourceManagerSettingsNode rootNode = (ResourceManagerSettingsNode)Hierarchy.FindNodeByType(ApplicationNode, typeof(ResourceManagerSettingsNode));
				Assert.IsNotNull(rootNode);
				Assert.AreEqual("ResourceManager1", rootNode.DefaultResourceManager.Name);

				Assert.AreEqual(1, ApplicationNode.Hierarchy.FindNodesByType(ApplicationNode, typeof(ResourceManagerSettingsNode)).Count);
				Assert.AreEqual(2, ApplicationNode.Hierarchy.FindNodesByType(ApplicationNode, typeof(ResourceManagerNode)).Count);
				Assert.AreEqual(2, ApplicationNode.Hierarchy.FindNodesByType(ApplicationNode, typeof(ResourceProviderNode)).Count);

				ApplicationNode.Hierarchy.Load();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);
				ApplicationNode.Hierarchy.Open();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);

				ResourceManagerCollectionNode resourceManagerCollectionNode = (ResourceManagerCollectionNode)ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(ResourceManagerCollectionNode));
				ResourceManagerNode resourceManagerNode = new ResourceManagerNode();
				resourceManagerCollectionNode.AddNode(resourceManagerNode);
				AddDataResourceProviderCommand cmd = new AddDataResourceProviderCommand(ServiceProvider);
				cmd.Execute(resourceManagerNode);
				DataResourceProviderNode dataNode = (DataResourceProviderNode)ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(DataResourceProviderNode));
				ConnectionStringSettingsNode connectNode = (ConnectionStringSettingsNode)ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(ConnectionStringSettingsNode));
				dataNode.DatabaseInstance = connectNode;
				Assert.AreEqual(1, Hierarchy.FindNodesByType(ApplicationNode, typeof(DatabaseSectionNode)).Count);

				ApplicationNode.Hierarchy.Save();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);

				ApplicationNode.Hierarchy.Load();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);
				ApplicationNode.Hierarchy.Open();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);

				Assert.AreEqual(1, ApplicationNode.Hierarchy.FindNodesByType(ApplicationNode, typeof(DataResourceProviderNode)).Count);

				dataNode = (DataResourceProviderNode)ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(DataResourceProviderNode));
				Assert.AreEqual(dataNode.DatabaseInstance.Name, connectNode.Name);

				DatabaseSectionNode databaseSectionNode = (DatabaseSectionNode)ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(DatabaseSectionNode));
				databaseSectionNode.Remove();

				dataNode.Remove();
				ApplicationNode.Hierarchy.Save();
				Assert.AreEqual(0, ErrorLogService.ConfigurationErrorCount);
			}
		}	

		[TestMethod]
		public void EnsureDatabaseSettingsAreAddedOnNewNode()
		{			
			AddResourceManagerSettingsNodeCommand resourceCmd = new AddResourceManagerSettingsNodeCommand(ServiceProvider);
			resourceCmd.Execute(ApplicationNode.Hierarchy.RootNode);

			ResourceManagerCollectionNode resourceManagerCollectionNode = (ResourceManagerCollectionNode)ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(ResourceManagerCollectionNode));
			ResourceManagerNode resourceManagerNode = new ResourceManagerNode();
			resourceManagerCollectionNode.AddNode(resourceManagerNode);
			AddDataResourceProviderCommand cmd = new AddDataResourceProviderCommand(ServiceProvider);
			cmd.Execute(resourceManagerNode);

			Assert.IsNotNull(ApplicationNode.Hierarchy.FindNodeByType(ApplicationNode, typeof(DatabaseSectionNode)));
		}
	}

	class ConfigFileSnapshot : IDisposable
	{
		private string contents;

		public ConfigFileSnapshot()
		{
			using (StreamReader rdr = new StreamReader(GetConfigFilePath()))
			{
				contents = rdr.ReadToEnd();
			}
		}

		public void Dispose()
		{
			if (contents != null)
			{
				using (StreamWriter writer = new StreamWriter(GetConfigFilePath(), false))
				{
					writer.Write(contents);
				}
				contents = null;
			}
		}

		private string GetConfigFilePath()
		{
			return AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
		}
	}
}